/****************************************************************************
 * taskapp
 * Tested MCU 
 * Owner : apleilx
 * **************************************************************************/
#define _TEMPLIB_MODULE_
#include "templib.h"

#ifndef INT16_MAX
#define INT16_MAX 0x7FFF
#endif

/*****************************************************************************//*!
*
* @brief   temperature calculate .
*          ad val to temperature       
* @param   none
*
* @return  none
*
* @ Pass/ Fail criteria: none
*****************************************************************************/

void TempCal(uint8_t Ch) {
    float Temp;
    float CalData, Cal;
    //    int32_t CalInt32;
    int16_t CalInt;
    int16_t x0, x1, y0, y1;
    int8_t Cnt;

    if (Ch >= TEMP_CH_AMOUNT)
        return;

    //linear transformation                                                     //y = (x - ADL) * (DIV_H - DIV_L)/(ADH - ADL)
    Temp = (TempADVal[Ch] - TempMarkTable[Ch].MarkADL)*(TEMP_DIVISION_MAX - TEMP_DIVISION_MIN);
    Temp /= (TempMarkTable[Ch].MarkADH - TempMarkTable[Ch].MarkADL);
    //    Temp      = CalInt32;
    //Non-linear correct with TempSensorTab                                     //y = (x-x0)*(y1-y0)/(x1-x0)
    CalData = TempSensorTab[0].Division;
    if (Temp < CalData) {
        Temp = TempSensorTab[0].Temp;
        TempErrSt[Ch] |= TEMP_ERR_TABLE_L_MASK;
    } else {
        TempErrSt[Ch] &= (uint8_t) (~TEMP_ERR_TABLE_L_MASK);
        Cnt = 0;
        do {
            Cnt++;
            CalData = TempSensorTab[Cnt].Division;
            CalInt = TempSensorTab[Cnt].Division;
        } while ((CalData < Temp) && (CalInt != INT16_MAX));

        if (INT16_MAX == CalInt) {
            Temp = TempSensorTab[Cnt - 1].Temp;
            TempErrSt[Ch] |= TEMP_ERR_TABLE_H_MASK;
        } else {
            TempErrSt[Ch] &= ~TEMP_ERR_TABLE_H_MASK;
            x1 = TempSensorTab[Cnt].Division;
            y1 = TempSensorTab[Cnt].Temp;
            x0 = TempSensorTab[Cnt - 1].Division;
            y0 = TempSensorTab[Cnt - 1].Temp;

            Temp = (Temp - x0) * (y1 - y0);
            Temp /= (x1 - x0);
            Temp += y0;
        }
    }

    //user correct                                                              //y = ( 1 + pk/4000)*x + pb
    CalData = Temp;
    Temp *= TempCorrectTable[Ch].PK;
    Temp /= 4000;
    Temp += CalData;
    Temp += TempCorrectTable[Ch].PB;

    CalData = TempLimiteTable[Ch].LimiteL - 20;
    Cal = TempLimiteTable[Ch].LimiteH + 20;
    if (Temp < CalData) {
        TempErrSt[Ch] |= (uint8_t) TEMP_ERR_LIMITE_L_MASK;
        Temp = CalData;
        //        return;
    } else if (Temp > Cal) {
        TempErrSt[Ch] |= (uint8_t) TEMP_ERR_LIMITE_H_MASK;
        Temp = Cal;
        //        return;
    } else {
        TempErrSt[Ch] &= ~(TEMP_ERR_LIMITE_L_MASK | TEMP_ERR_LIMITE_H_MASK);
    }

    //y = 0.7 * last + 0.3 * cur
    CalData = Temperature[Ch];
    Temp = CalData * 0.7 + Temp * 0.3;
    Temperature[Ch] = Temp;

    CalData = TemperatureDisp[Ch];
    Temp = CalData * 0.85 + Temp * 0.15;
    TemperatureDisp[Ch] = Temp;
}

/*****************************************************************************//*!
*
* @brief   get temperature .
*               
* @param   none
*
* @return  none
*
* @ Pass/ Fail criteria: none
*****************************************************************************/

int16_t TempGet(uint8_t Ch) {
    if (Ch >= TEMP_CH_AMOUNT) {
        return INT16_MAX;
    } else {
        if (Temperature[Ch] < 0)
            return (int16_t) (Temperature[Ch] - 0.5);
        else
            return (int16_t) (Temperature[Ch] + 0.5);
    }

    //    return  (int16_t)Temperature[Ch];
}

/*****************************************************************************//*!
*
* @brief   get temperature For display.
*               
* @param   none
*
* @return  none
*
* @ Pass/ Fail criteria: none
*****************************************************************************/

int16_t DispTempGet(uint8_t Ch) {

    if (Ch >= TEMP_CH_AMOUNT) {
        return INT16_MAX;
    } else {
        if (Temperature[Ch] < 0)
            return (int16_t) (TemperatureDisp[Ch] - 0.5);
        else
            return (int16_t) (TemperatureDisp[Ch] + 0.5);
    }

    //    return  (int16_t)TemperatureDisp[Ch];
}

/*****************************************************************************//*!
*
* @brief   set Ad val .
*               
* @param   none
*
* @return  none
*
* @ Pass/ Fail criteria: none
*****************************************************************************/

void TempADSet(uint8_t Ch, int16_t AD_Val) {
    if (Ch >= TEMP_CH_AMOUNT)
        return;
    else
        TempADVal[Ch] = AD_Val;
}

/*****************************************************************************//*!
*
* @brief   Get error .
*                
* @param   none
*
* @return  none
*
* @ Pass/ Fail criteria: none
*****************************************************************************/

uint8_t TempErrGet(uint8_t Ch) {
    if (Ch >= TEMP_CH_AMOUNT)
        return 0;
    else
        return TempErrSt[Ch];
}
